﻿using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Linq;
using System.Text;

namespace gt.webapi.core.Entity.Common
{
    public class SuccessResult<T> : IHttpActionResult
    {
        T m_data;
        HttpRequestMessage m_request;
        public SuccessResult(T data, HttpRequestMessage request)
        {
            this.m_data = data;
            this.m_request = request;
        }
        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var result = new ApiResponse<T>(this.m_data);
            var response = this.m_request.CreateResponse<ApiResponse<T>>(result);
            return Task.FromResult(response);
        }
    }
    public class ErrorResult : IHttpActionResult
    {
        int m_code;
        string m_errorMsg;
        HttpRequestMessage m_request;
        public ErrorResult(int code, string errorMsg, HttpRequestMessage request)
        {
            this.m_code = code;
            this.m_errorMsg = errorMsg;
            this.m_request = request;
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var result = new ApiResponse<string>(this.m_code, this.m_errorMsg);
            var response = this.m_request.CreateResponse<ApiResponse<string>>(result);
            return Task.FromResult(response);
        }
    }
    public class AddChallengeOnUnauthorizedResult : IHttpActionResult
    {
        public AddChallengeOnUnauthorizedResult(AuthenticationHeaderValue challenge, IHttpActionResult innerResult)
        {
            Challenge = challenge;
            InnerResult = innerResult;
        }

        public AuthenticationHeaderValue Challenge { get; private set; }

        public IHttpActionResult InnerResult { get; private set; }

        public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            //invoker inner result to create response
            HttpResponseMessage response = await InnerResult.ExecuteAsync(cancellationToken);

            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                // Only add one challenge per authentication scheme.
                if (!response.Headers.WwwAuthenticate.Any((h) => h.Scheme == Challenge.Scheme))
                {
                    response.Headers.WwwAuthenticate.Add(Challenge);
                }
            }

            return response;
        }
    }
    public class AuthenticationFailureResult : IHttpActionResult
    {
        public AuthenticationFailureResult(string reasonPhrase, HttpRequestMessage request)
        {
            ReasonPhrase = reasonPhrase;
            Request = request;
        }

        public string ReasonPhrase { get; private set; }

        public HttpRequestMessage Request { get; private set; }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            return Task.FromResult(Execute());
        }

        private HttpResponseMessage Execute()
        {
            HttpResponseMessage response = new System.Net.Http.HttpResponseMessage
            {
                RequestMessage = Request,
                ReasonPhrase = ReasonPhrase,
                StatusCode = System.Net.HttpStatusCode.Unauthorized,
                Content = new StringContent(ReasonPhrase, Encoding.UTF8, Constants.API_CONTENT_MEDIATPE_TEXT)
            };
            return response;
        }
    }
}
